-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
ref(onboarding): Introduce content blocks #95224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
ref(onboarding): Introduce content blocks #95224
Conversation
const partialLoading = useMemo( | ||
() => children.includes(PACKAGE_LOADING_PLACEHOLDER), | ||
[children] | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously we had a separate prop partiallyLoading
on the configuration object, which was missing most of the time. I decided to drop it from the new format and rather autodetect the loading placeholder in the snippet. This solution is maybe a bit hacky but is much better DX when writing docs.
* | ||
* **Do not** use this with custom react elements but instead use the `custom` block type. | ||
*/ | ||
text: React.ReactNode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would love to only have string
here. Also the translation functions are making the docs so much harder to read...
Codecov ReportAll modified and coverable lines are covered by tests ✅ ✅ All tests successful. No failed tests found. Additional details and impacted files@@ Coverage Diff @@
## master #95224 +/- ##
=======================================
Coverage 87.84% 87.85%
=======================================
Files 10469 10469
Lines 605374 605361 -13
Branches 23674 23672 -2
=======================================
- Hits 531819 531814 -5
+ Misses 73195 73187 -8
Partials 360 360 |
export type ContentBlock = | ||
| TextBlock | ||
| CodeBlock | ||
| CustomBlock | ||
| AlertBlock | ||
| ConditionalBlock; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just added the most basic ones that I encountered while converting java & react docs.
In the future we will for sure add more like heading
, list
, ...
type: 'custom', | ||
content: ( | ||
<OnboardingCodeSnippet | ||
language="bash" | ||
onCopy={() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onCopy
and onSelectAndCopy
was only supported for this one usage. Decided to resort to a custom block instead of bloating the interface.
import { | ||
getProfilingDocumentHeaderConfigurationStep, | ||
MaybeBrowserProfilingBetaWarning, | ||
} from 'sentry/components/onboarding/gettingStartedDoc/utils/profilingOnboarding'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch removing profiling 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah there is even more to do here! will create a ticket for it
static/app/components/onboarding/gettingStartedDoc/contentBlocks/defaultBlocks.tsx
Outdated
Show resolved
Hide resolved
`; | ||
|
||
function TextBlock(block: Extract<ContentBlock, {type: 'text'}>) { | ||
return <TextBlockWrapper>{block.text}</TextBlockWrapper>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return <TextBlockWrapper>{block.text}</TextBlockWrapper>; | |
return <div css={css`${baseBlockStyles} code:not([class*='language-']) { | |
color: ${p => p.theme.pink400}; | |
}`}>{block.text}</div>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 though I will move the style definition out of the render function so they are not serialized on every render
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah no, it needs the theme so I cant transform it to css
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use useTheme
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh i find <TextBlockWrapper>{block.text}</TextBlockWrapper>
way nicer and easier to work with then
<div css={css`${baseBlockStyles} code:not([class*='language-']) {
color: ${p => p.theme.pink400};
}`}>{block.text}</div>;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have have a strong opinion here, but I am always in favour of having less code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, I checked the implementation of styled
. It always serializes styles during render.
So from a performance view, static styles should be faster with the css
annotation outside the component. But as soon as you use the theme or props inside the css it does not make a difference (at least with regards to style serialization).
Edit: My bad did not see that styled
already implements a cache based on the template result. Same goes for the css prop handling. So no difference.
export const defaultBlocks: BlockRenderer = { | ||
text: TextBlock, | ||
code: CodeBlock, | ||
custom: CustomBlock, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused about having a customBlock inside of defaultBlocks. is it a default custom block?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If i get this correctly it is a block component that is used by default when the type of the block is custom.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it is the default renderer for the block with type custom
and just adds a wrapper div with margin so devs writing some custom jsx in the docs do not have to care about the spacing between content.
the block type custom
is meant as the escape hatch if no other blocks fit:
/**
* Custom blocks can be used to render any content that is not covered by the other block types.
*/
type CustomBlock = BaseBlock<'custom'> & {
content: React.ReactNode;
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I get that, just the name is confusing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe it helps renaming defaultBlocks
to defaultRenderers
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR has quite a few changes, which made it difficult to review...though I understand it was probably needed for the proof of concept. I’ve gone through all the code, and it looks really good. I especially like the comments you added to the new props and how you marked the old ones as deprecated. I also compared the rendered components to what we have in production, and everything seems just right. Nice work! 🚀
It might take me and maybe others a little time to get used to the new content blocks, but I think they’ll make our code cleaner and easier to work with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const baseBlockStyles = css` | ||
:not(:last-child) { | ||
margin-bottom: var(${CssVariables.BLOCK_SPACING}); | ||
} | ||
`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use a <Alert.Container> here? It should add the margin for you
ContentBlock, | ||
} from 'sentry/components/onboarding/gettingStartedDoc/contentBlocks/types'; | ||
|
||
export enum CssVariables { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use a styled component here?
I would suggest finding a more specific naming here given that these are exported, you wouldn't want them to pollute LSP suggestions.
Introduce specialized content blocks opposed to the current configuration object.
This makes it clearer what is rendered in which order and which properties are required -> enforced by types.
Converted react and java project creation onboarding docs. (also removed not-needed profiling content from react docs)